﻿function BasicTreeRenderer(tvh) {
	this.render = function(column, record, contextInfo) {
		var indent = contextInfo.level * 15, node = contextInfo.node;
		var label = $('<span>').css('padding-left', 22).html(record[column.field]);
		var item = $('<span>').addClass('dt-tree-node').css('padding-left', 16 + indent).append(label).css('background-position', indent+'px center');
		
		if (node.children.length > 0) {
			item.addClass(node.collapsed ? 'dt-tree-node-plus': 'dt-tree-node-minus');
			label.addClass(node.collapsed ? 'dt-tree-folder-closed': 'dt-tree-folder-open');
		} else {
			label.addClass('dt-tree-leaf');
		}
		
		item.click(function(e) {
			e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation();
			tvh.toggle(node);
		});
		
		tvh.items.put(node, item);
		
		return item;
	};
}

function TreeViewHandler(options) {
	var _this = this;
	this.grid = null;
	this.count = -1;
	this.items = new Map();
	
	this.toggle = function(node){
		node.collapsed ? this.expand(node): this.collapse(node);
		this.grid.pageChanged.trigger();
	};
	
	this.expand = function(node) {
		this._toggleNode(node, false, function(child) {
			var visible = true;
			var n = child.parent;
			while (n != node) {
				visible &= !n.collapsed;
				n = n.parent;
			}
			return visible;
		});
	};
	this.collapse = function(node) {
		this._toggleNode(node, true, function() {return false});
	};
	
	this._toggleNode = function(node, collapsed, isVisible) {
		if (node.children.length > 0) {
			var item = this.items.get(node);
			item.removeClass('dt-tree-node-minus dt-tree-node-plus').addClass(collapsed ? 'dt-tree-node-plus': 'dt-tree-node-minus');
			item.find('span').removeClass('dt-tree-folder-closed dt-tree-folder-open').addClass(collapsed ? 'dt-tree-folder-closed':'dt-tree-folder-open');
			
			node.collapsed = collapsed;
			var getDescendants = function(node) {
				var d = node.children.slice(0);
				for (var i=0;i < node.children.length;i++) d = d.concat(getDescendants(node.children[i]));
				return d;
			}
			
			var descendants = getDescendants(node);
			
			for (var i=0;i < descendants.length;i++) {
				var child = descendants[i];
				$(child.row).css('display', isVisible(child) ? '': 'none');
			}
			_this.grid.resize();
		}
	};
	
	this.collapseAll = function() {
		var nodes = _this.grid.getAllNodes();
		
		for (var i=0;i < nodes.length;i++) {
			if (nodes[i].parent!=null) this.collapse(nodes[i]);
		}
		this.grid.pageChanged.trigger();
	};
	
	this.expandAll = function() {
		var nodes = _this.grid.getAllNodes();
		for (var i=0;i<nodes.length;i++) {
			if (nodes[i].parent!=null) this.expand(nodes[i]);
		}
		this.grid.pageChanged.trigger();
	};
	
	this.get = function(from, to, callback) {
		this.grid.dataLoader.get(from, to, function(data) {
			_this.count = data.total;
			
			var atree = new Node({root: "root"});
			var mr = new Map();
			for (var i=0;i< data.items.length;i++) {
				var id = data.items[i][options.id];
				var node = new Node(data.items[i]);
				
				mr.put(id, node);
			}
			
			var nodes = mr.values();
			
			for (var i=0;i< nodes.length;i++) {
				var parentId = nodes[i].record.parent;
				
				if (parentId == -1) {
					atree.addChild(nodes[i]);
				} else {
					var p = mr.get(parentId);
					if (p != null) {
						p.addChild(nodes[i]);
					} else {
						atree.addChild(nodes[i]);
					}
				}
			}
			
			callback(data, atree);
			_this.grid.renderPage(atree);
			_this.grid.pageChanged.trigger();
		});
	}
	
	this.attachListener = function() {
		_this.grid.refresh();
	};
	
	this.oldColumnRenderer = null;
	this.toolbarWidget = null;
	
	this.attach = function(grid) {
		this.grid = grid;
		this.toolbarWidget = $('<span>');
		
		var btnCollapseTree = $('<button>').html('Collapse all').button({icons: {primary: "ui-icon-minus"}}).click(function() {
			_this.collapseAll();
		});
		
		var btnExpandTree = $('<button>').html('Expand all').button({icons: {primary: "ui-icon-plus"}}).click(function() {
			_this.expandAll();
		});
		
		this.toolbarWidget.append(btnCollapseTree);
		this.toolbarWidget.append(btnExpandTree);
		
		if (this.grid.addToolbarWidget) this.grid.addToolbarWidget(this.toolbarWidget);
		for (var c=0;c < this.grid.options.columns.length;c++) {
			if (this.grid.options.columns[c].field == options.id) {
				this.oldColumnRenderer = this.grid.options.columns[c].renderer;
				this.grid.options.columns[c].renderer = new BasicTreeRenderer(this);
				break;
			}
		}

		this.grid.loader = this;
		this.grid.attached.add(this.attachListener);
		
		if (this.grid.isAttached) this.grid.refresh();
	};
	
	this.detach = function() {
		this.grid.removeToolbarWidget(this.toolbarWidget);
		for (var c=0;c < this.grid.options.columns.length;c++) {
			if (this.grid.options.columns[c].field == options.id) {
				this.grid.options.columns[c].renderer = this.oldColumnRenderer;
			}
		}
		this.grid.attached.remove(this.attachListener);
		this.grid.loader = null;
	};
}; TreeViewHandler.inherits(DatagridPlugin);